﻿//-----------------------------------------------------------------------
// <copyright file="FacetCollection.cs" company="Forebrain Technology, LLC">
//
// Copyright (c) Forebrain Technology, LLC. All rights reserved.
// 
// This source code is released under the Microsoft Public License (Ms-PL).
//
// </copyright>
//-----------------------------------------------------------------------
namespace PivotCollectionTools.Xml
{
    using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.Linq;
    using System.Xml.Serialization;

    /// <summary>
    /// Represents a list of <see cref="Facet"/> objects that can be accessed by an index. Provides methods to 
    /// search, sort, and manipulate the <see cref="Facet"/> objects in the list.
    /// </summary>
    [Serializable()]
    [XmlType(Namespace = "http://schemas.microsoft.com/collection/metadata/2009")]
    public class FacetCollection : Collection<Facet>
    {
        /// <summary>
        /// Gets the <see cref="Facet"/> with the specified facet name.
        /// </summary>
        /// <param name="facetName">The facet name of the facet to get.</param>
        public Facet this[string facetName]
        {
            get { return this.Items.FirstOrDefault(f => f.FacetName == facetName); }
        }

        /// <summary>
        /// Adds a <see cref="Facet"/> of <see cref="FacetStringType"/> to the end of the Facet list 
        /// with the specified facet name and text.
        /// </summary>
        /// <param name="name">The name of the facet.</param>
        /// <param name="text">The text value for the facet.</param>
        public void AddTextFacet(string name, string text)
        {
            if (this.Contains(name))
            {
                this[name].Text.Add(new FacetStringType(text));
                return;
            }

            var newFacet = new Facet(name);
            newFacet.Text.Add(new FacetStringType(text));
            this.Add(newFacet);
        }

        /// <summary>
        /// Adds a <see cref="Facet"/> of <see cref="FacetStringType"/> to the end of the Facet list 
        /// with the specified facet name and list of text.
        /// </summary>
        /// <param name="name">The name of the facet.</param>
        /// <param name="textList">The list of text for the facet.</param>
        public void AddTextFacet(string name, IEnumerable<string> textList)
        {
            if (this.Contains(name))
            {
                foreach (var text in textList)
                {
                    this[name].Text.Add(new FacetStringType(text));
                }

                return;
            }

            var newFacet = new Facet(name);
            foreach (var text in textList)
            {
                newFacet.Text.Add(new FacetStringType(text));
            }

            this.Add(newFacet);
        }

        /// <summary>
        /// Adds a facet of type number to the list.
        /// </summary>
        /// <param name="name">The name of the facet.</param>
        /// <param name="value">The value of the facet.</param>
        public void AddNumberFacet(string name, decimal value)
        {
            if (this.Contains(name))
            {
                this[name].Number.Add(new FacetNumberType(value));
                return;
            }

            var newFacet = new Facet(name);
            newFacet.Number.Add(new FacetNumberType(value));
            this.Add(newFacet);
        }

        /// <summary>
        /// Determines whether this collection has the specified facet name.
        /// </summary>
        /// <param name="facetName">Name of the facet.</param>
        /// <returns>
        /// <c>true</c> if this contains the specified facet name; otherwise, <c>false</c>.
        /// </returns>
        public bool Contains(string facetName)
        {
            return this.Items.Any(f => f.FacetName == facetName);
        }
    }
}
